home *** CD-ROM | disk | FTP | other *** search
/ NOVA - For the NeXT Workstation / NOVA - For the NeXT Workstation.iso / SourceCode / TextORama / TextORama.m < prev    next >
Text File  |  1992-12-19  |  4KB  |  193 lines

  1. /* TextORama.m
  2.  *
  3.  *   TextORama is a subclass of Object which acts as the
  4.  * application delegate.
  5.  * 
  6.  *
  7.  * You may freely copy, distribute, and reuse the code in this example.
  8.  * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
  9.  * fitness for any particular use.
  10.  *
  11.  * Written by:  Sharon Zakhour 
  12.  * Created:  Oct/91
  13.  */
  14.  
  15. #import "TextORama.h"
  16. #import "TurboTextField.h"
  17. #import "TurboTFCell.h"
  18. #import <appkit/Font.h>
  19. #import <appkit/ScrollView.h>
  20. #import <appkit/publicWraps.h>
  21. #import <stdlib.h>
  22.  
  23. @implementation TextORama
  24.  
  25. - appDidInit:sender
  26. {
  27.     id font;
  28.     
  29.     font = [Font newFont: "Helvetica" size: 16.0];
  30.     
  31.     [dateField setAutoJump:YES forLength:8];
  32.     [dateField setCustomFilter: (NXTextFilterFunc)dateFilter];
  33.     [[dateField cell] setFont: font];
  34.  
  35.     [socSecField setAutoJump:YES forLength:11];
  36.     [socSecField setCustomFilter: (NXTextFilterFunc)socSecFilter];
  37.     [[socSecField cell] setFont: font];
  38.  
  39.     [phoneField setMaxLength:8];
  40.     [phoneField setCustomFilter: (NXTextFilterFunc)phoneFilter];
  41.     [[phoneField cell] setFont: font];
  42.     
  43.     [self loadEmacsScrollView];
  44.     
  45.     return self;
  46. }
  47.  
  48.  
  49. #define IS_DATE_DELIMITER(ch) ((ch) == '/')
  50. #define IS_PHONE_DELIMITER(ch) ((ch) == '-')
  51. #define IS_NUMBER(ch) ((ch) >= '0' && (ch) <= '9')
  52. #define IS_LETTER(ch) ((ch) >= 'a' && (ch) <= 'z' || (ch) >= 'A' && (ch) <= 'Z')
  53.  
  54. // This could easily be extended to include letters with diacritics.
  55. // See Chapter 6 Summary for KeyInfo for a full listing of keyboard
  56. // event information.
  57. #define IS_VALID_ASCII(ch)    ((ch) >= ' ' && (ch) <= '~')
  58.  
  59. char *dateFilter(id textObj, char *inputText, int *inputLength, int position)
  60. {
  61.     BOOL ok = NO;
  62.     char    dateString[10];
  63.     int        dateLength, tmp;
  64.     
  65.     switch(position) 
  66.     {
  67.  
  68.     case 2: case 5:
  69.         ok = IS_DATE_DELIMITER(*inputText);
  70.         if (!ok && IS_VALID_ASCII(*inputText))  NXBeep();
  71.         break;
  72.  
  73.     default:
  74.         ok = IS_NUMBER(*inputText);
  75.         if (!ok && IS_VALID_ASCII(*inputText))  NXBeep();
  76.         break;
  77.     }
  78.     
  79.     // Let's do some actual date validation...
  80.     dateLength = [textObj textLength];
  81.     [textObj getSubstring:dateString start:0 length:dateLength];
  82.     
  83.     if (!ok)
  84.     {
  85.     *inputLength = 0;
  86.     return "";
  87.     }
  88.     
  89.     switch (dateLength)
  90.     {
  91.     case 1:
  92.     dateString[1] = '\0';
  93.     tmp = atoi(&dateString[0]);
  94.     ok = (tmp == 0 || tmp == 1);
  95.     break;
  96.     case 2:
  97.     dateString[2] = '\0';
  98.     tmp = atoi(&dateString[0]);
  99.     ok = (tmp >= 1 && tmp <= 12);
  100.     break;
  101.     case 4:
  102.     dateString[4] = '\0';
  103.     tmp = atoi(&dateString[3]);
  104.     ok = (tmp >= 0 && tmp <= 3);
  105.     break;
  106.     case 5:
  107.     dateString[5] = '\0';
  108.     tmp = atoi(&dateString[3]);
  109.     ok = (tmp >= 1 && tmp <= 31);
  110.     break;
  111.     case 7:
  112.     dateString[7] = '\0';
  113.     tmp = atoi(&dateString[6]);
  114.     ok = (tmp == 8 || tmp == 9);
  115.     break;
  116.     case 8:
  117.     dateString[8] = '\0';
  118.     tmp = atoi(&dateString[6]);
  119.     ok = (tmp >= 80 && tmp <= 99);
  120.     break;
  121.     }
  122.     
  123.     if (ok) return inputText;
  124.     *inputLength = 0;
  125.     return "";
  126. }
  127.  
  128. char *socSecFilter(id textObj, char *inputText, int *inputLength, int position)
  129. {
  130.     BOOL ok = NO;
  131.     
  132.     switch(position) 
  133.     {
  134.     case 3: case 6:
  135.         ok = IS_PHONE_DELIMITER(*inputText);
  136.         if (!ok && IS_VALID_ASCII(*inputText))  NXBeep();
  137.         break;
  138.  
  139.     default:
  140.         ok = IS_NUMBER(*inputText);
  141.         if (!ok && IS_VALID_ASCII(*inputText))  NXBeep();
  142.         break;
  143.     }
  144.     if (ok) return inputText;
  145.     *inputLength = 0;
  146.     return "";
  147. }
  148.  
  149. char *phoneFilter(id textObj, char *inputText, int *inputLength, int position)
  150. {
  151.     BOOL ok = NO;
  152.     
  153.     switch(position) 
  154.     {
  155.     case 3:
  156.         ok = IS_PHONE_DELIMITER(*inputText);
  157.         if (!ok && IS_VALID_ASCII(*inputText))  NXBeep();
  158.         break;
  159.  
  160.     default:
  161.         ok = IS_NUMBER(*inputText);
  162.         if (!ok && IS_VALID_ASCII(*inputText))  NXBeep();
  163.         break;
  164.     }
  165.     if (ok) return inputText;
  166.     *inputLength = 0;
  167.     return "";
  168. }
  169.  
  170. // Load the EMACS window with some text so that we can play with the emacs
  171. // bindings!!
  172. - loadEmacsScrollView
  173. {
  174.     id  theTO;
  175.     NXStream *s = (NXStream *)nil;
  176.     
  177.     theTO = [emacsScrollView docView];
  178.     
  179.     // Open a memory stream on the data file and read it into the text object.           
  180.     s = NXMapFile("SoapStory.rtf", NX_READONLY);
  181.     if (s)
  182.     {
  183.     [theTO readRichText:s];
  184.     NXCloseMemory(s, NX_FREEBUFFER);
  185.     }
  186.     
  187.     [[emacsScrollView window] orderFront:nil];
  188.     
  189.     return self;
  190. }
  191.  
  192. @end
  193.